package com.gexiaobao.pigeon.ui.fragment.login

import android.annotation.SuppressLint
import android.os.Build
import android.os.Bundle
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.TextPaint
import android.text.method.HideReturnsTransformationMethod
import android.text.method.LinkMovementMethod
import android.text.method.PasswordTransformationMethod
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.view.View
import android.widget.LinearLayout
import android.widget.ListPopupWindow
import androidx.core.content.ContextCompat
import androidx.core.view.isVisible
import androidx.fragment.app.setFragmentResultListener
import androidx.lifecycle.lifecycleScope
import com.gexiaobao.pigeon.R
import com.gexiaobao.pigeon.app.App
import com.gexiaobao.pigeon.app.base.BaseFragment
import com.gexiaobao.pigeon.app.eventViewModel
import com.gexiaobao.pigeon.app.ext.Constant
import com.gexiaobao.pigeon.app.ext.countDownCoroutines
import com.gexiaobao.pigeon.app.ext.hideSoftKeyboard
import com.gexiaobao.pigeon.app.ext.showMessage
import com.gexiaobao.pigeon.app.model.param.GetVerCodeParams
import com.gexiaobao.pigeon.app.model.param.LoginCodeParams
import com.gexiaobao.pigeon.app.model.param.LoginParams
import com.gexiaobao.pigeon.app.model.param.ResetPwdParams
import com.gexiaobao.pigeon.app.util.CacheUtil
import com.gexiaobao.pigeon.app.util.KvUtils
import com.gexiaobao.pigeon.app.util.LanguageUtil
import com.gexiaobao.pigeon.app.util.RxToast
import com.gexiaobao.pigeon.app.util.StatusBarUtil
import com.gexiaobao.pigeon.app.util.Util
import com.gexiaobao.pigeon.databinding.FragmentLoginBinding
import com.gexiaobao.pigeon.ui.activity.ActivityPrivacyAndService
import com.gexiaobao.pigeon.ui.activity.LoginActivity
import com.gexiaobao.pigeon.ui.activity.MainActivity
import com.gexiaobao.pigeon.ui.activity.bank.ActivitySigningDocument
import com.gexiaobao.pigeon.ui.adapter.AddBloodPigeonPopAdapter
import com.gexiaobao.pigeon.ui.dialog.RxDialogModifyPsw
import com.gexiaobao.pigeon.ui.dialog.RxDialogSingle
import com.gexiaobao.pigeon.ui.fragment.mine.pigeon.activity.ActivityShedRace
import com.gexiaobao.pigeon.ui.organizer.ActivityMemberInfo
import com.gexiaobao.pigeon.ui.pilot.activity.ReleaseMissionActivity
import com.gexiaobao.pigeon.viewmodel.LoginViewModel
import me.hgj.jetpackmvvm.ext.nav
import me.hgj.jetpackmvvm.ext.navigateAction
import me.hgj.jetpackmvvm.ext.parseState
import me.hgj.jetpackmvvm.ext.util.setOnclickNoRepeat
import me.hgj.jetpackmvvm.util.LogUtils
import me.hgj.jetpackmvvm.util.startActivity
import me.jessyan.autosize.internal.CustomAdapt


/**
 * @Author      : hxw
 * @Date        : 2023/5/31 10:55
 * @Describe    :
 */
class LoginFragment : BaseFragment<LoginViewModel, FragmentLoginBinding>(), CustomAdapt {

    private var userName: String = ""
    private var isShowPwd = false
    private var mIsRePwd = false
    private lateinit var dialog: RxDialogModifyPsw
    private var isCodeLogin = false

    private val popWindowLanguage: ListPopupWindow by lazy { context?.let { ListPopupWindow(it) }!! }
    private var adapter: AddBloodPigeonPopAdapter? = null
    private var mLanguagePosition = 0
    private var mListLanguage: MutableList<String> = arrayListOf()

    override fun initView(savedInstanceState: Bundle?) {
        mDatabind.viewmodel = mViewModel
        activity?.let { StatusBarUtil.setLightMode(it) }

        val language = CacheUtil.getLanguage()
        val tvLanguage: String
        when (language) {
            "pt_BR" -> {
                mLanguagePosition = 2
                tvLanguage = "Português"
            }

            "en_US" -> {
                mLanguagePosition = 1
                tvLanguage = "English"
            }

            else -> {
                mLanguagePosition = 0
                tvLanguage = getString(R.string.chinese)
            }
        }
        mDatabind.tvLanguage.text = tvLanguage
        userName = KvUtils.decodeString(Constant.USER_NAME)
        initSpannableText()
        mDatabind.checkRememberPwd.setOnCheckedChangeListener { _, isChecked ->
            mIsRePwd = isChecked
        }
        val mobileLogin = KvUtils.decodeString(Constant.USER_NAME_MOBILE)
        mDatabind.etUserNameMobile.setText(mobileLogin)

        initPopup()

        setFragmentResultListener("requestIsCode") { _, bundle ->
            isCodeLogin = bundle.getBoolean("isCodeLogin")
            isCodeLogin = !isCodeLogin
            changeLoginType()
        }

        popWindowLanguage.setOnItemClickListener { _, _, position, _ ->
            mLanguagePosition = position
            adapter!!.setCheckItem(position)
            mDatabind.tvLanguage.text = mListLanguage[position]
            val langu: String
            val languageHeader: String
            when (position) {
                2 -> {
                    languageHeader = "pt_BR"
                    langu = "pt"
                }

                1 -> {
                    languageHeader = "en_US"
                    langu = "en"
                }

                else -> {
                    languageHeader = "zh_CN"
                    langu = "zh"
                }
            }
            activity?.let { it1 -> LanguageUtil.changeAppLanguage(it1, langu, LoginActivity::class.java) }
            CacheUtil.setLanguage(languageHeader)
            CacheUtil.setLanguageApp(langu)
            popWindowLanguage.dismiss()
        }
    }

    private fun initPopup() {
        mListLanguage = arrayListOf(getString(R.string.chinese), "English", "Português")
        adapter = AddBloodPigeonPopAdapter(context, mListLanguage)
        popWindowLanguage.setAdapter(adapter)
        popWindowLanguage.anchorView = mDatabind.llLanguage//设置ListPopupWindow的锚点，关联mButton位置
        popWindowLanguage.width = LinearLayout.LayoutParams.WRAP_CONTENT
        popWindowLanguage.height = LinearLayout.LayoutParams.WRAP_CONTENT
        popWindowLanguage.isModal = true
        adapter!!.setCheckItem(mLanguagePosition)
    }

    override fun onResume() {
        super.onResume()
        val userPassword = KvUtils.decodeString(Constant.USER_PASSWORD)
        val isRePwd = KvUtils.decodeBoolean(Constant.IS_CHECKED_PASSWORD)
        mIsRePwd = isRePwd
        if (isRePwd) {
            mViewModel.username.set(userName)
            mViewModel.password.set(userPassword)
        }
        mDatabind.checkRememberPwd.isChecked = isRePwd
    }

    @SuppressLint("UseCompatLoadingForDrawables")
    override fun onBindViewClick() {
        super.onBindViewClick()
        setOnclickNoRepeat(
            mDatabind.tvNewUserRegister,
            mDatabind.ivLoginCleanAccount,
            mDatabind.ivShowPassword,
            mDatabind.loginForgetPassword,
            mDatabind.tvLoginCommit,
            mDatabind.tvCodeToLogin,
            mDatabind.tvSendLoginCode,
            mDatabind.ivLoginCleanMobile,
            mDatabind.etUserName,
            mDatabind.llLanguage
        ) {
            when (it.id) {
                R.id.llLanguage -> popWindowLanguage.show()
                R.id.ivLoginCleanMobile -> {
                    mDatabind.etUserNameMobile.setText("")
                    mDatabind.etLoginCode.setText("")
                }

                R.id.tvSendLoginCode -> countDownCode()
                R.id.tvCodeToLogin -> changeLoginType()
                R.id.tv_new_user_register -> {
                    hideSoftKeyboard(activity)
                    nav().navigateAction(R.id.action_login_to_register, Bundle().apply {
                        putBoolean("isCodeLogin", isCodeLogin)
                    })
                }

                R.id.iv_login_clean_account -> cleanStatus()
                R.id.iv_show_password -> {
                    if (isShowPwd) {
                        mDatabind.ivShowPassword.setBackgroundResource(R.mipmap.ic_password_see_on)
                        mDatabind.etLoginPassword.transformationMethod = HideReturnsTransformationMethod.getInstance()
                    } else {
                        mDatabind.ivShowPassword.setBackgroundResource(R.mipmap.ic_password_see)
                        mDatabind.etLoginPassword.transformationMethod = PasswordTransformationMethod.getInstance()
                    }
                    isShowPwd = !isShowPwd
                    mDatabind.etLoginPassword.text?.let { it1 -> mDatabind.etLoginPassword.setSelection(it1.length) }
                }

                R.id.login_forget_password -> {
                    hideSoftKeyboard(activity)
                    nav().navigateAction(R.id.action_login_to_retrieve_pwd)
                }

                R.id.tv_login_commit -> login()
            }
        }
    }

    private fun changeLoginType() {
        if (!isCodeLogin) {
            mDatabind.llMobileLogin.isVisible = true
            mDatabind.tvCodeToLogin.text = getString(R.string.password_login)
            mDatabind.llNameLogin.isVisible = false
            mDatabind.llRemember.isVisible = false
        } else {
            mDatabind.llRemember.isVisible = true
            mDatabind.llMobileLogin.isVisible = false
            mDatabind.tvCodeToLogin.text = getString(R.string.Verification_code_login)
            mDatabind.llNameLogin.isVisible = true
        }
        isCodeLogin = !isCodeLogin
    }

    @SuppressLint("SetTextI18n")
    private fun countDownCode() {
        val mobile = mDatabind.etUserNameMobile.text.toString().trim()
        val body = GetVerCodeParams(mobile, 4)
        when {
            mobile.isEmpty() -> showMessage(resources.getString(R.string.user_mobile_number))
            !Util.isTelPhoneNumber(mobile) -> showMessage(resources.getString(R.string.user_phone_number_wrong))
            else -> {
                //开启倒计时60s
                job = countDownCoroutines(60, {
                    mDatabind.tvSendLoginCode.text = it.toString() + getString(R.string.after_Get_the_verification_code)
                }, {
                    mDatabind.tvSendLoginCode.text = getString(R.string.Get_the_verification_code)
                }, lifecycleScope)
                mViewModel.getVerCode(body)
            }
        }
    }

    private fun cleanStatus() {
        mViewModel.username.set("")
        mViewModel.password.set("")
        mDatabind.checkRememberPwd.isChecked = false
        mDatabind.checkUserPolicy.isChecked = false
    }

    private fun login() {
        if (!isCodeLogin) {
            when {
                //showMessage("请先阅读并同意《用户服务协议》和《隐私政策》")
                mViewModel.username.get().isEmpty() -> showMessage(resources.getString(R.string.user_name))
                mViewModel.password.get().isEmpty() -> showMessage(resources.getString(R.string.user_password))
                !mDatabind.checkUserPolicy.isChecked -> showPrivacyDialog()
                else -> {
                    val bodyLogin = LoginParams(
                        name = mViewModel.username.get().trim(),
                        password = mViewModel.password.get().trim(),
                        deviceId = App.instance.deviceId
                    )
                    showLoading(getString(R.string.loading))
                    mViewModel.login(bodyLogin)
                }
            }
        } else {
            when {
                mDatabind.etUserNameMobile.text.toString().isEmpty() -> showMessage(getString(R.string.user_mobile_number))
                mDatabind.etLoginCode.text.toString().trim().isEmpty() -> showMessage(getString(R.string.user_verification_code))
                !mDatabind.checkUserPolicy.isChecked -> showPrivacyDialog()
                else -> {
                    val bodyLogin = LoginCodeParams(
                        mobile = mDatabind.etUserNameMobile.text.toString().trim(),
                        code = mDatabind.etLoginCode.text.toString().trim(),
                        deviceId = App.instance.deviceId
                    )
                    showLoading("登录中...")
                    mViewModel.codeLogin(bodyLogin)
                }
            }
        }
    }

    private fun showPrivacyDialog() {
        val dialog = RxDialogSingle(context)
        dialog.setTitle(getString(R.string.read_user_service))
        dialog.setSureListener {
            dialog.dismiss()
            mDatabind.checkUserPolicy.isChecked = true
            login()
        }
        dialog.setFullScreenWidth()
        dialog.show()
    }

    override fun createObserver() {
        super.createObserver()
        /** 重置密码 */
        mViewModel.mResultReSet.observe(viewLifecycleOwner) { resultState ->
            parseState(resultState, {
                RxToast.showToast(getString(R.string.Password_changed_successfully))
                dialog.dismiss()
                mViewModel.password.set("")
            }, {
                RxToast.showToast(it.msg)
            })
        }

        mViewModel.loginResult.observe(viewLifecycleOwner) {
            if (it.modifyNeed == 1) {
                showModifyPswDialog()
                return@observe
            }
            /** 登录成功之后保存token，需要后续添加在请求头中，保存用户名和密码 */
            CacheUtil.setToken(it.token)
            CacheUtil.setIsLogin(true)
            KvUtils.encode(Constant.USERID, it.userId)
            KvUtils.encode(Constant.ROLE, it.role)
            KvUtils.encode(Constant.ORG_ID, it.orgId)
            KvUtils.encode(Constant.TOKEN, it.token)
            KvUtils.encode(Constant.ORG_USER_ID, it.id)
            KvUtils.encode(Constant.USER_NAME, it.name)
            KvUtils.encode(Constant.USER_NAME_MOBILE, mDatabind.etUserNameMobile.text.toString().trim())
            KvUtils.encode(Constant.IS_CHECKED_PASSWORD, mIsRePwd)
            KvUtils.encode(Constant.USER_PASSWORD, mViewModel.password.get())
            eventViewModel.isLogin.value = true

            LogUtils.debugInfo("userID:" + it.userId)
            if (it.role != 4 && it.role != 3 && it.role != 1 && it.role != 5 && it.role != 2) {
                showMessage(getString(R.string.User_permissions_are_incorrect))
                return@observe
            }
            intentRelationalActivity(it.role)
        }

        mViewModel.mOrgIdResult.observe(viewLifecycleOwner) {
            if (it != null) {
                dismissLoading()
                KvUtils.encode(Constant.ORGANIZATION_ID, it.orgId)
                startActivity<ReleaseMissionActivity>()
                activity?.finish()
            }
        }
    }

    private fun intentRelationalActivity(role: Int) {
        when (role) {//4-用户，3-放飞员，1-组织方 5-银行 2-公棚收鸽
            1 -> {
                dismissLoading()
                startActivity<ActivityMemberInfo>()
                KvUtils.encode(Constant.ORGANIZATION_NAME, mViewModel.username.get())
                activity?.finish()
            }

            4 -> {
                dismissLoading()
                startActivity<MainActivity>()
                activity?.finish()
            }

            3 -> mViewModel.getOrg()
            5 -> startActivity<ActivitySigningDocument>()
            2 -> startActivity<ActivityShedRace>("type" to 1)
            else -> {
                dismissLoading()
                startActivity<MainActivity>()
                activity?.finish()
            }
        }
    }

    private fun showModifyPswDialog() {
        dialog = RxDialogModifyPsw(context)
        dialog.setSendCodeListener {
            getVerifyCode(dialog)
        }
        dialog.setSureListener {
            changePwd(dialog)
        }
        dialog.setFullScreenWidth()
        dialog.show()
    }

    private fun changePwd(dialog: RxDialogModifyPsw) {
        when {
            dialog.forgetPhone.text.toString().trim().isEmpty() -> showMessage(resources.getString(R.string.user_mobile_number))
            !Util.isTelPhoneNumber(dialog.forgetPhone.text.toString().trim()) -> showMessage(
                resources.getString(
                    R.string.user_phone_number_wrong
                )
            )

            dialog.forgetCode.text.toString().trim().isEmpty() -> showMessage(resources.getString(R.string.user_verification_code))
            dialog.forgetCode.text.toString().trim().length != 6 -> showMessage(
                resources.getString(
                    R.string.user_verification_code_wrong
                )
            )

            dialog.forgetPwd.text.toString().trim().isEmpty() -> showMessage(resources.getString(R.string.user_password))
            dialog.forgetRepeatPwd.text.toString().trim().isEmpty() -> showMessage(
                resources.getString(
                    R.string.user_repeat_password
                )
            )

            dialog.forgetPwd.text.toString().trim() != dialog.forgetRepeatPwd.text.toString()
                .trim() -> showMessage(resources.getString(R.string.user_password_not_alike))

            else -> {
                val body =
                    ResetPwdParams(
                        dialog.forgetPhone.text.toString().trim(),
                        dialog.forgetCode.text.toString().trim(),
                        dialog.forgetPwd.text.toString().trim()
                    )
                mViewModel.reSetPwd(body)
            }
        }
    }

    @SuppressLint("SetTextI18n")
    private fun getVerifyCode(dialog: RxDialogModifyPsw) {
        val phone = dialog.forgetPhone.text.toString().trim()
        when {
            phone.isEmpty() -> showMessage(resources.getString(R.string.user_mobile_number))
            !Util.isTelPhoneNumber(phone) -> showMessage(resources.getString(R.string.user_phone_number_wrong))
            else -> {
                //开启倒计时60s
                job = countDownCoroutines(60, {
                    dialog.forgetVerifyCodeSend.text = "${it}s"
                }, {
                    dialog.forgetVerifyCodeSend.text = getString(R.string.Get_the_verification_code)
                }, lifecycleScope)
                val body = GetVerCodeParams(phone, 4)
                mViewModel.getVerCode(body)
            }
        }
    }


    private fun initSpannableText() {
        val clickSpan: ClickableSpan = object : ClickableSpan() {
            override fun onClick(widget: View) {
                startActivity<ActivityPrivacyAndService>("type" to "1")
            }

            override fun updateDrawState(ds: TextPaint) {
                ds.isUnderlineText = false
            }
        }
        val clickSpanService: ClickableSpan = object : ClickableSpan() {
            override fun onClick(widget: View) {
                startActivity<ActivityPrivacyAndService>("type" to "2")
            }

            override fun updateDrawState(ds: TextPaint) {
                ds.isUnderlineText = false
            }
        }

        val spannable = SpannableStringBuilder(
            getString(R.string.have_read_and_agree)
        )
        /** 这个一定要记得设置，不然点击不生效 */
        mDatabind.tvUserPolicy.movementMethod = LinkMovementMethod.getInstance()
        /** 设置文字的前景色 */
        spannable.setSpan(clickSpanService, 7, 15, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        spannable.setSpan(
            ForegroundColorSpan(ContextCompat.getColor(requireContext(), R.color.colorPrimary)),
            7,
            15,
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        spannable.setSpan(clickSpan, 16, spannable.length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        spannable.setSpan(
            ForegroundColorSpan(ContextCompat.getColor(requireContext(), R.color.colorPrimary)),
            16,
            spannable.length,
            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        )
        mDatabind.tvUserPolicy.text = spannable
    }

    override fun isBaseOnWidth(): Boolean {
        return false
    }

    override fun getSizeInDp(): Float {
        return when (Build.MANUFACTURER) {
            "realme", "vivo", "OPPO" -> Constant.LANDSCREENFLOAT
            "HUAWEI" -> Constant.LANDSCREENFLOATHW
            else -> Constant.LANDSCREENFLOATS
        }
    }
}